package com.zhuzhe.blog.question.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhuzhe.blog.base.BaseRequest;
import com.zhuzhe.blog.base.JsonData;
import com.zhuzhe.blog.base.ResponseData;
import com.zhuzhe.blog.category.responseVo.LabellistVo;
import com.zhuzhe.blog.convert.Convert;
import com.zhuzhe.blog.question.entity.Question;
import com.zhuzhe.blog.question.entity.QuestionThumhup;
import com.zhuzhe.blog.question.entity.Replay;
import com.zhuzhe.blog.feign.label.IFeignLabelController;
import com.zhuzhe.blog.question.mapper.QuestionMapper;
import com.zhuzhe.blog.question.mapper.QuestionThumhupMapper;
import com.zhuzhe.blog.question.mapper.ReplayMapper;
import com.zhuzhe.blog.question.requestDto.QuestionDto;
import com.zhuzhe.blog.question.requestDto.QuestionThumhupDto;
import com.zhuzhe.blog.question.requestDto.QuestionUserDto;
import com.zhuzhe.blog.question.responseVo.QuestionPageVo;
import com.zhuzhe.blog.question.responseVo.QuestionVo;
import com.zhuzhe.blog.question.service.IQuestionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhuzhe.blog.utils.GetIpUtil;
import com.zhuzhe.blog.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 问题信息表 服务实现类
 * </p>
 *
 * @author u53
 * @since 2020-10-08
 */
@Service
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> implements IQuestionService {

    private static final String REDIS_QUESTION = "_question_";

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private IFeignLabelController feignArticleController;

    @Autowired
    private QuestionThumhupMapper questionThumhupMapper;

    @Autowired
    private ReplayMapper replayMapper;

    @Override
    public ResponseData<IPage<QuestionPageVo>> findHotList(BaseRequest<Question> baseRequestDto) {
        QueryWrapper<Question> wrapper = new QueryWrapper<>();
        // 1. 状态为 1 或 2，不能查询0（已删除）的
        wrapper.in(Question.STATUS, Arrays.asList(1, 2));
        // 2. 按 回复数 降序排列
        wrapper.orderByDesc(Question.REPLY);
        IPage<Question> list = baseMapper.selectPage(baseRequestDto.getPage(), wrapper);
        IPage<QuestionPageVo> page = new Page<>();
        Convert.convertType(list,page);
        List<QuestionPageVo> questionPageVos = Convert.convertList(list.getRecords(),QuestionPageVo.class);
        page.setRecords(questionPageVos);
        return JsonData.success(page);
    }

    @Override
    public ResponseData<IPage<QuestionPageVo>> findNewList(BaseRequest<Question> req) {
        QueryWrapper<Question> wrapper = new QueryWrapper<>();
        // 1. 状态为 1 或 2，不能查询0（已删除）的
        wrapper.in(Question.STATUS, Arrays.asList(1, 2));
        // 按 更新时间 降序排列，
        wrapper.orderByDesc(Question.UPDATE_DATE);
        IPage<Question> list = baseMapper.selectPage(req.getPage(), wrapper);
        IPage<QuestionPageVo> page = new Page<>();
        Convert.convertType(list,page);
        List<QuestionPageVo> questionPageVos = Convert.convertList(list.getRecords(),QuestionPageVo.class);
        page.setRecords(questionPageVos);
        return JsonData.success(page);
    }

    @Override
    public ResponseData<IPage<QuestionPageVo>> findWaitList(BaseRequest<Question> req) {
        QueryWrapper<Question> wrapper = new QueryWrapper<>();
        // 1. 状态为 1 或 2，不能查询0（已删除）的
        wrapper.in(Question.STATUS, Arrays.asList(1, 2));
        // 2. 回复数是 0
        wrapper.eq(Question.REPLY, 0);
        // 3. 按创建时间降序排列
        wrapper.orderByDesc(Question.CREATE_DATE);

        IPage<Question> list = baseMapper.selectPage(req.getPage(), wrapper);
        IPage<QuestionPageVo> page = new Page<>();
        Convert.convertType(list,page);
        List<QuestionPageVo> questionPageVos = Convert.convertList(list.getRecords(),QuestionPageVo.class);
        page.setRecords(questionPageVos);
        return JsonData.success(page);
    }

    @Override
    public ResponseData<IPage<QuestionPageVo>> findListByLabelId(BaseRequest<Question> baseRequest, String labelId) {
        if(StringUtils.isEmpty(labelId)) {
            return JsonData.fail("标签ID不能为空");
        }
        IPage<Question> list = baseMapper.findListByLabelId(baseRequest.getPage(), labelId) ;
        IPage<QuestionPageVo> page = new Page<>();
        Convert.convertType(list,page);
        List<QuestionPageVo> questionPageVos = Convert.convertList(list.getRecords(),QuestionPageVo.class);
        page.setRecords(questionPageVos);
        return JsonData.success(page);
    }


    @Override
    public ResponseData<QuestionVo> findById(String id , String userId) {
        // 1. 查询问题详情与标签ids
        QuestionVo questionVo =  baseMapper.findQuestionAndLabelIdsById(id);
        if(null == questionVo) {
            return JsonData.fail("未获取问题详情信息");
        }
        if (StringUtils.isEmpty(userId)){
            questionVo.setThumhupBool(true);
        }else {
            QueryWrapper<QuestionThumhup> queryWrapper = new QueryWrapper();
            queryWrapper.eq(QuestionThumhup.QUESTION_ID,id)
                    .eq(QuestionThumhup.USER_ID,userId);
            QuestionThumhup questionThumhup = questionThumhupMapper.selectOne(queryWrapper);
            if (null == questionThumhup){
                questionVo.setThumhupBool(true);
            }else{
                questionVo.setThumhupBool(false);
            }
        }

        // 2. Feign 远程调用  Category 服务查询标签信息
        if(CollectionUtils.isNotEmpty(questionVo.getLabelIds())) {
            List<LabellistVo> labelList = feignArticleController.getLabelListByIds(questionVo.getLabelIds());
            questionVo.setLabelList(labelList);
        }
        return JsonData.success(questionVo);
    }


    @Override
    public ResponseData<String> updateViewCount(String id , HttpServletRequest request) {

        String key = GetIpUtil.getIp(request)+REDIS_QUESTION+id;
        //查询该ip 是否 访问过 此文章
        if(redisUtil.hasKey(key)){
            return JsonData.success();
        }
        if(StringUtils.isEmpty(id)) {
            return JsonData.fail("无效操作");
        }

        // 查询问题详情
        Question question = baseMapper.selectById(id);
        if(question == null) {
            return JsonData.fail("问题不存在");
        }
        //浏览记录存入redis 时长 5分钟 ,5分钟之内不该ip 访问不累加浏览次数
        redisUtil.set(key,null,60*5);
        // 浏览数+1
        question.setViewCount( question.getViewCount() + 1 );
        baseMapper.updateById(question);

        return JsonData.success(question.getId());
    }

    @Override
    @Transactional
    public ResponseData<String>  updateOrSave(QuestionDto questionDto) {
//        1. 如果是更新，删除 zhuzhe_question_lable 问题标签中间表数据，且设置更新时间
        Question question = new Question();
        Convert.convertType(questionDto,question);
        if(StringUtils.isNotEmpty( questionDto.getId() )) {
            baseMapper.deleteQuestionLabel(questionDto.getId());
            question.setUpdateDate(new Date());
        }
//        2. 问题数据新增或更新到 zhuzhe_question 表
        super.saveOrUpdate(question);

//        3. 问题所属标签保存到 zhuzhe_question_lable 表
        if(CollectionUtils.isNotEmpty(questionDto.getLabelIds())) {
            baseMapper.saveQuestionLabel(question.getId(), questionDto.getLabelIds());
        }

        // 4. 响应当前操作的问题id
        return JsonData.success(question.getId());
    }

    @Override
    public ResponseData<String> deleteById(String id) {
        return this.updateStatus(id, 0); // 0 表示删除
    }



    /**
     * 修改问题状态值
     * @param id 问题id
     * @param status 问题状态
     * @return
     */
    public ResponseData<String> updateStatus(String id, Integer status) {

        // 通过问题id查询问题详情
        Question question = baseMapper.selectById(id);
        // 设置新状态值
        question.setStatus(status);
        question.setUpdateDate(new Date());

        baseMapper.updateById(question);
        return JsonData.success(question.getId());
    }

    @Override
    @Transactional
    public ResponseData<String> updateThumhup(QuestionThumhupDto questionThumhupDto) {
        if(questionThumhupDto.getCount() != -1 && questionThumhupDto.getCount() != 1) {
            return JsonData.fail("无效操作");
        }
        if(StringUtils.isEmpty(questionThumhupDto.getQuestionId())) {
            return JsonData.fail("无效操作");
        }

        Question question = baseMapper.selectById(questionThumhupDto.getQuestionId());
        if(question == null) {
            return JsonData.fail("问题不存在");
        }

        if(question.getThumhup() <= 0 && questionThumhupDto.getCount() == -1) {
            return JsonData.fail("无效操作");
        }

        QueryWrapper<QuestionThumhup> queryWrapper = new QueryWrapper();
        queryWrapper.eq(QuestionThumhup.QUESTION_ID,questionThumhupDto.getQuestionId())
                .eq(QuestionThumhup.USER_ID,questionThumhupDto.getUserId());
        QuestionThumhup questionThumhup = questionThumhupMapper.selectOne(queryWrapper);
        //判断传入是否为 1 如果传入 1 查看关联表中是否存在数据,如果存在数据则无法继续点赞
        if (questionThumhupDto.getCount() == 1){
            if (questionThumhup != null){
                return JsonData.fail("该文章已经点赞过");
            }
        }

        //判断传入是否为 -1 如果传入 -1 说明是取消点赞删除关联表中数据
        if (questionThumhupDto.getCount() == -1){
            if (null == questionThumhup){
                return JsonData.fail("未赞过该文章,无法取消点赞！");
            }
            questionThumhupMapper.delete(queryWrapper);
        }
        question.setThumhup( question.getThumhup() + questionThumhupDto.getCount() );
        baseMapper.updateById(question);
        QuestionThumhup  questionThumhupa = new QuestionThumhup();
        questionThumhupa.setQuestionId(question.getId());
        questionThumhupa.setUserId(question.getUserId());
        questionThumhupMapper.insert(questionThumhupa);
        return JsonData.success();
    }

    @Override
    public ResponseData<IPage<QuestionPageVo>> findListByUserId(QuestionUserDto questionUserDto) {
        if(StringUtils.isEmpty(questionUserDto.getUserId())) {
            return JsonData.fail("无效用户信息");
        }

        QueryWrapper<Question> wrapper = new QueryWrapper<>();
        wrapper.in(Question.STATUS, Arrays.asList(1, 2));
        // 根据用户id查询
        wrapper.eq(Question.USER_ID, questionUserDto.getUserId());
        // 排序
        wrapper.orderByDesc(Question.CREATE_DATE);
        IPage<Question> list =  baseMapper.selectPage(questionUserDto.getPage(), wrapper);
        IPage<QuestionPageVo> page = new Page<>();
        Convert.convertType(list,page);
        List<QuestionPageVo> questionPageVos = Convert.convertList(list.getRecords(),QuestionPageVo.class);
        page.setRecords(questionPageVos);
        return JsonData.success(page);
    }

    @Override
    public ResponseData<Integer> getQuestionTotal() {
        QueryWrapper<Question> wrapper = new QueryWrapper<>();
        // 状态不能是删除的（0），应该是 1 和 2
        wrapper.in(Question.STATUS, Arrays.asList(1, 2));

        Integer total = baseMapper.selectCount(wrapper);
        return JsonData.success(total);
    }



    @Override
    @Transactional
    public ResponseData<String> adoptionQuetion(String id, String replyid) {
        //验证码 问题id 和 回答id 是否有问题
        if (StringUtils.isEmpty(id) ||
            StringUtils.isEmpty(replyid)){
            return JsonData.fail("传入正确参数");
        }
        // 查询问题详情与标签ids
        QuestionVo questionVo = baseMapper.findQuestionAndLabelIdsById(id);
        if (null == questionVo){
            return JsonData.fail("该问题不存在");
        }

        Question question = new Question();
        Convert.convertType(questionVo,question);
        question.setUpdateDate(new Date());
        question.setStatus(1);
        baseMapper.updateById(question);
        this.updateStatus(id,2);
        Replay replay = replayMapper.selectById(replyid);
        if (null == replay){
            return JsonData.fail("该评论不存在");
        }
        replay.setAdoption(1);
        replayMapper.updateById(replay);
        return JsonData.success(question.getId());
    }
}
